package com.xmy.cultivate.service.impl;

import com.aliyun.facebody20191230.Client;
import com.aliyun.facebody20191230.models.*;
import com.aliyun.tea.TeaException;
import com.xmy.cultivate.entity.LogRecord;
import com.xmy.cultivate.entity.Organization;
import com.xmy.cultivate.mapper.FaceDbMapper;
import com.xmy.cultivate.mapper.OrganizationMapper;
import com.xmy.cultivate.service.IAliyunFaceService;
import com.xmy.cultivate.service.ILogRecordService;
import com.xmy.cultivate.service.IOssUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AliyunFaceServiceImpl implements IAliyunFaceService {

    @Autowired
    IOssUploadService iOssUploadService;

    @Autowired
    FaceDbMapper faceDbMapper;

    @Value("${aliyun.AccessKeyID}")
    String accessKeyId;

    @Value("${aliyun.AccessKeySecret}")
    String accessKeySecret;

    @Value("${aliyun.face.endpoint}")
    String faceEndpoint;

    @Value("${aliyun.face.DbName}")
    String DbName;

    @Autowired
    @Lazy
    OrganizationMapper organizationMapper;

    @Autowired
    @Lazy
    ILogRecordService iLogRecordService;


    public Client createClient(Long schoolId) throws Exception {

        Organization schoolInfo = organizationMapper.selectById(schoolId);
        if(schoolInfo != null){
            this.accessKeyId = schoolInfo.getAccessKeyId();
            this.accessKeySecret = schoolInfo.getAccessKeySecret();
        }

        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(this.accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(this.accessKeySecret);
        // 访问的域名
        config.endpoint = this.faceEndpoint;
        return new Client(config);
    }

    /**
     * 添加人脸样本
     * @param entityId
     * @param lables
     * @return
     * @throws Exception
     */
    @Override
    public boolean addFaceSample(Long schoolId,String DbName,String entityId,String lables) throws Exception {
        Client client = this.createClient(schoolId);
        AddFaceEntityRequest addFaceEntityRequest = new AddFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(entityId)
                .setLabels(lables);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        AddFaceEntityResponse addFaceEntityResponse = client.addFaceEntityWithOptions(addFaceEntityRequest, runtime);
        /*try {
            // 复制代码运行请自行打印 API 的返回值
            AddFaceEntityResponse addFaceEntityResponse = client.addFaceEntityWithOptions(addFaceEntityRequest, runtime);
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        }*/
        return false;
    }

    /**
     * 修改人脸样本
     * @param entityId
     * @param lables
     * @return
     * @throws Exception
     */
    @Override
    public boolean updateFaceSample(Long schoolId,String DbName,String entityId,String lables) throws Exception {
        Client client = this.createClient(schoolId);
        UpdateFaceEntityRequest updateFaceEntityRequest = new UpdateFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(entityId)
                .setLabels(lables);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        client.updateFaceEntityWithOptions(updateFaceEntityRequest, runtime);
        /*try {
            // 复制代码运行请自行打印 API 的返回值

        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        }*/
        return false;
    }

    public boolean delFaceSample(Long schoolId,String DbName,String entityId) throws Exception {
        Client client = this.createClient(schoolId);
        DeleteFaceEntityRequest deleteFaceEntityRequest = new DeleteFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(entityId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.deleteFaceEntityWithOptions(deleteFaceEntityRequest, runtime);
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        }
        return true;
    }


    /**
     * 批量删除人脸样本数据
     * @param schoolId
     * @param DbName
     * @return
     * @throws Exception
     */
    public boolean delListFaceSample(Long schoolId,String DbName) throws Exception {
        Client client = this.createClient(schoolId);
        ListFaceEntitiesRequest listFaceEntitiesRequest = new ListFaceEntitiesRequest()
                .setDbName(DbName).setLimit(200);;
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            ListFaceEntitiesResponse listFaceEntitiesResponse = client.listFaceEntitiesWithOptions(listFaceEntitiesRequest, runtime);
            List<ListFaceEntitiesResponseBody.ListFaceEntitiesResponseBodyDataEntities> listFaceEntitiesResponses = listFaceEntitiesResponse.getBody().getData().getEntities();
            for (ListFaceEntitiesResponseBody.ListFaceEntitiesResponseBodyDataEntities entities: listFaceEntitiesResponses){
                String entityId2 = entities.getEntityId();
                this.delFaceSample(schoolId,DbName,entityId2);
            }
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        }
        return true;
    }

    /**
     * 删除人脸样本数据
     * @param schoolId
     * @param DbName
     * @return
     * @throws Exception
     */
    public boolean delFaceSampleForEntityId(Long schoolId,String DbName,String entityId) throws Exception {
        Client client = this.createClient(schoolId);
        DeleteFaceEntityRequest deleteFaceEntityRequest = new DeleteFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(entityId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.deleteFaceEntityWithOptions(deleteFaceEntityRequest, runtime);
            //System.out.println("删除成功");
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        }
        return true;
    }




    /**
     * 获取人脸样本数据
     * @param schoolId
     * @param DbName
     * @return
     * @throws Exception
     */
    public boolean getFaceSampleForEntityId(Long schoolId,String DbName,String EntityId) throws Exception {
        Client client = this.createClient(schoolId);
        GetFaceEntityRequest getFaceEntityRequest = new GetFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(EntityId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            GetFaceEntityResponse getFaceEntityResponse = client.getFaceEntityWithOptions(getFaceEntityRequest, runtime);
            GetFaceEntityResponseBody.GetFaceEntityResponseBodyData getFaceEntityResponseBodyData = getFaceEntityResponse.getBody().getData();
            if (getFaceEntityResponseBodyData != null){
                List<GetFaceEntityResponseBody.GetFaceEntityResponseBodyDataFaces> faceEntityResponseBodyDataFaceList = getFaceEntityResponseBodyData.getFaces();
                for (GetFaceEntityResponseBody.GetFaceEntityResponseBodyDataFaces faceEntityResponseBodyDataFaces:faceEntityResponseBodyDataFaceList)
                {
                    //System.out.println("faceEntityResponseBodyDataFaces.getFaceId:"+faceEntityResponseBodyDataFaces.getFaceId());
                }
            }
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        }
        return true;
    }



    /**
     * 判断人脸实体是否存在
     * @return
     */
    public boolean existFaceSample(Long schoolId,String DbName,String entityId) throws Exception {
        Client client = this.createClient(schoolId);
        GetFaceEntityRequest getFaceEntityRequest = new GetFaceEntityRequest()
                .setDbName(DbName)
                .setEntityId(entityId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        GetFaceEntityResponse getFaceEntityResponse = client.getFaceEntityWithOptions(getFaceEntityRequest, runtime);
        if(getFaceEntityResponse.getBody().getData() !=null){
            return true;
        }else {
            return false;
        }

        /*try {
            // 复制代码运行请自行打印 API 的返回值
            GetFaceEntityResponse getFaceEntityResponse = client.getFaceEntityWithOptions(getFaceEntityRequest, runtime);
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
        }*/
    }

    /**
     * 添加人脸数据
     * @param imageUrl
     * @param entityId
     * @param extraData
     * @return
     * @throws Exception
     */
    @Override
    public AddFaceResponse addFaceData(Long schoolId,String DbName,String imageUrl,String entityId,String extraData) throws Exception {

        Client client = this.createClient(schoolId);
        AddFaceRequest addFaceRequest = new AddFaceRequest()
                .setDbName(DbName)
                .setImageUrl(imageUrl)
                .setEntityId(entityId)
                .setQualityScoreThreshold(70F)//质量分阈值。对新增人脸图片进行质量分析判断，得到的质量分小于该阈值则表示新增人脸图片质量不符合要求，添加失败。取值范围[0.0,100.0]。0.0或空则表示不做质量分判断逻辑。
                //.setSimilarityScoreThresholdInEntity(90F)//将新增人脸图片与EntityId内已有人脸进行相似比对，小于该阈值则表示与其他人脸图片差异较大，添加失败.；若EntityId内没有人脸存在，则添加成功。取值范围[0.0,100.0]。0.0或空则表示不做类内相似度判断逻辑
                .setSimilarityScoreThresholdBetweenEntity(93F)//将新增人脸图片与其他所有EntityId内已有人脸进行相似比对，大于等于该阈值则表示其他EntityId内存在相似人脸，出现重复，添加失败。取值范围[0.0,100.0]。0.0或空则表示不做类间相似度判断逻辑
                .setExtraData(extraData);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        //AddFaceResponse addFaceResponse = client.addFaceWithOptions(addFaceRequest, runtime);
        AddFaceResponse addFaceResponse = null;
        try {
            // 复制代码运行请自行打印 API 的返回值
            addFaceResponse = client.addFaceWithOptions(addFaceRequest, runtime);
        } catch (TeaException error) {
            //System.out.println("getCode");
            //System.out.println(error.getCode());

            addFaceResponse = new AddFaceResponse();
            addFaceResponse.setStatusCode(50000);

            LogRecord logRecord = new LogRecord();
            logRecord.setContent(imageUrl);
            logRecord.setRemark("添加人脸:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);
            // 如有需要，请打印 error
            //com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            //System.out.println("getCode02");
            //System.out.println(error.getCode());
            //com.aliyun.teautil.Common.assertAsString(error.message);
            LogRecord logRecord = new LogRecord();
            logRecord.setContent(imageUrl);
            logRecord.setRemark("添加人脸:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);

            addFaceResponse.setStatusCode(50001);
        }
        return addFaceResponse;
    }

    /**
     * 删除人脸数据
     * @param faceId
     * @return
     * @throws Exception
     */
    @Override
    public boolean delFaceData(Long schoolId,String DbName,String faceId) throws Exception {
        Client client = this.createClient(schoolId);
        DeleteFaceRequest deleteFaceRequest = new DeleteFaceRequest()
                .setDbName(DbName)
                .setFaceId(faceId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.deleteFaceWithOptions(deleteFaceRequest, runtime);
            return true;
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);

            LogRecord logRecord = new LogRecord();
            logRecord.setRemark("删除人脸:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            LogRecord logRecord = new LogRecord();
            logRecord.setRemark("删除人脸:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);

            return false;
        }
    }

    /**
     * 搜索人脸
     * @param imageUrl
     * @return
     * @throws Exception
     */
    public SearchFaceResponse searchFace(String DbName,Long schoolId,String imageUrl) throws Exception {

        /*QueryWrapper<FaceDb> faceDbQueryWrapper = new QueryWrapper<>();
        List<FaceDb> faceDbList = faceDbMapper.selectList(faceDbQueryWrapper);
        StringBuilder dbNamesBuilder = new StringBuilder();
        for (FaceDb faceDb:faceDbList){
            dbNamesBuilder.append(faceDb.getDbName()).append(",");
        }
        String  dbNames = dbNamesBuilder.toString();
        dbNames = dbNames.substring(0,dbNames.length()-1);
        System.out.println("dbNames:"+dbNames);*/
        Client client = this.createClient(schoolId);
        SearchFaceRequest searchFaceRequest = new SearchFaceRequest()
                .setDbName(DbName)
                .setLimit(10)
                .setQualityScoreThreshold(65F)
                .setMaxFaceNum(1L)
                .setImageUrl(imageUrl);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        SearchFaceResponse searchFaceResponse = client.searchFaceWithOptions(searchFaceRequest, runtime);

        //System.out.println("searchFaceResponse");
        //System.out.println(searchFaceResponse);
        return searchFaceResponse;
        /*try {
            // 复制代码运行请自行打印 API 的返回值
            SearchFaceResponse searchFaceResponse = client.searchFaceWithOptions(searchFaceRequest, runtime);
            return searchFaceResponse;
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            System.out.println("=============1"+error.message);
            return null;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            System.out.println("=============2"+error.message);
            return null;
        }*/

    }

    /**
     * 搜索人脸，返回EntityId
     * @param imageUrl
     * @return
     * @throws Exception
     */
    public String searchFaceReturnEntityId(String DbName,Long schoolId,String imageUrl) throws Exception {

        /*QueryWrapper<FaceDb> faceDbQueryWrapper = new QueryWrapper<>();
        List<FaceDb> faceDbList = faceDbMapper.selectList(faceDbQueryWrapper);
        StringBuilder dbNamesBuilder = new StringBuilder();
        for (FaceDb faceDb:faceDbList){
            dbNamesBuilder.append(faceDb.getDbName()).append(",");
        }
        String  dbNames = dbNamesBuilder.toString();
        dbNames = dbNames.substring(0,dbNames.length()-1);
        System.out.println("dbNames:"+dbNames);*/
        Client client = this.createClient(schoolId);
        SearchFaceRequest searchFaceRequest = new SearchFaceRequest()
                .setDbName(DbName)
                .setLimit(10)
                .setQualityScoreThreshold(90F)
                .setMaxFaceNum(1L)
                .setImageUrl(imageUrl);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            SearchFaceResponse searchFaceResponse = client.searchFaceWithOptions(searchFaceRequest, runtime);
            if(searchFaceResponse.getBody().getData() == null){
                return null;
            }

            List<SearchFaceResponseBody.SearchFaceResponseBodyDataMatchList> searchFaceResponseBodyDataMatchList = searchFaceResponse.getBody().getData().getMatchList();
            if(searchFaceResponseBodyDataMatchList.size()>0){
                SearchFaceResponseBody.SearchFaceResponseBodyDataMatchList faceResponseBodyDataMatchList = searchFaceResponseBodyDataMatchList.get(0);

                Float QualitieScore = faceResponseBodyDataMatchList.getQualitieScore();
                Float confidence = Float.parseFloat("90.62");//转换后的置信度
                Float score = Float.parseFloat("0.6");//人脸的相似度

                //Float maxConfidence = Float.parseFloat("0");
                //Float maxScore = Float.parseFloat("0");

                SearchFaceResponseBody.SearchFaceResponseBodyDataMatchListFaceItems findFaceResponseBodyDataMatchListFaceItem = null;
                for (SearchFaceResponseBody.SearchFaceResponseBodyDataMatchListFaceItems searchFaceResponseBodyDataMatchFaceItems:faceResponseBodyDataMatchList.getFaceItems()){
                    if(findFaceResponseBodyDataMatchListFaceItem == null){
                        findFaceResponseBodyDataMatchListFaceItem = searchFaceResponseBodyDataMatchFaceItems;
                    }else {
                        //System.out.println("searchFaceResponseBodyDataMatchFaceItems.getConfidence:"+searchFaceResponseBodyDataMatchFaceItems.getConfidence());
                        if(findFaceResponseBodyDataMatchListFaceItem != null && searchFaceResponseBodyDataMatchFaceItems.getConfidence() > findFaceResponseBodyDataMatchListFaceItem.getConfidence()){
                            findFaceResponseBodyDataMatchListFaceItem = searchFaceResponseBodyDataMatchFaceItems;
                        }
                    }
                }
                /*if(findFaceResponseBodyDataMatchListFaceItem !=null){
                    maxConfidence = findFaceResponseBodyDataMatchListFaceItem.getConfidence();
                    maxScore = findFaceResponseBodyDataMatchListFaceItem.getScore();
                }*/
                if(findFaceResponseBodyDataMatchListFaceItem !=null && findFaceResponseBodyDataMatchListFaceItem.getConfidence() >= confidence && findFaceResponseBodyDataMatchListFaceItem.getScore()>score){
                    String entityId = findFaceResponseBodyDataMatchListFaceItem.getEntityId();
                    String faceId = findFaceResponseBodyDataMatchListFaceItem.getFaceId();
                    return faceId+","+entityId;
                }
            }
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            //System.out.println("=============1"+error.message);
            LogRecord logRecord = new LogRecord();
            logRecord.setContent(imageUrl);
            logRecord.setRemark("校区id:"+schoolId+"，人脸搜索:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);

            return "error";
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);

            LogRecord logRecord = new LogRecord();
            logRecord.setContent(imageUrl);
            logRecord.setRemark("校区id:"+schoolId+"，人脸搜索:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);
            //System.out.println("=============2"+error.message);
            return "error";
        }
        return null;
    }


    /**
     * 创建人脸数据库
     * @param schoolId
     * @param DbName
     * @return
     * @throws Exception
     */
    public boolean addFaceDb(Long schoolId,String DbName) throws Exception {
        Client client =  this.createClient(schoolId);
        CreateFaceDbRequest createFaceDbRequest = new CreateFaceDbRequest()
                .setName(DbName);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.createFaceDbWithOptions(createFaceDbRequest, runtime);
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            LogRecord logRecord = new LogRecord();
            logRecord.setRemark("添加人脸数据库:"+error.message);
            logRecord.setLevel(6);
            iLogRecordService.save(logRecord);
            return false;
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            return false;
        }
        return true;
    }





}
